import { createReducer, createAsyncAction, createAction } from 'redux-action-tools';
let configA = {
  authDomain: "kmxxg-chat.wilddog.com",
  syncURL: "https://kmxxg-chat.wilddogio.com"
};

let chatApp = wilddog.initializeApp(configA, "APP_A");
let chatAppRef = wilddog.sync();
let upRef = wilddog.sync().ref("up-metadata");
let roomMetaRef = wilddog.sync().ref("room-metadata");
let roomMessageRef = wilddog.sync().ref("room-messages");
let usersRef = wilddog.sync().ref("users");
let provider = new wilddog.auth.WeixinAuthProvider();
//========================================================================
//点赞活动的reducer
//========================================================================
const GETUPLIST = 'GETUPLIST',
  ADDONEUP = 'ADDONEUP',
  DELETEONEUP = 'DELETEONEUP',
  UPDATEUPCOUNT = 'UPDATEUPCOUNT';


export const getUpList = createAsyncAction(GETUPLIST, () => {
  return upRef.orderByChild('createdAt').limitToLast(1000).once('value');
})

export const addOneUp = createAsyncAction(ADDONEUP, (payload, dispatch) => {
  // console.log(payload);
  let newUpRef = upRef.push();
  payload = Object.assign({}, payload, { createdAt: upRef.ServerValue.TIMESTAMP, id: newUpRef.key() });
  // console.log(payload, chatAppRef.ServerValue);
  return newUpRef.set(payload).then(data => {
    dispatch(getUpList());
    return data;
  })
});

export const deleteOneUp = createAsyncAction(DELETEONEUP, (valueId, dispatch) => {
  return upRef.ref(valueId).set(null).then(data => {
    dispatch(getUpList());
    return data;
  });
})
export const updateUpCount = createAsyncAction(UPDATEUPCOUNT, (valueObj, dispatch) => {
  return wilddog.sync().ref('up-metadata').child(valueObj.id).set(valueObj).then(data => {
    dispatch(getUpList());
    return data;
  });
})

const GETUPLIST_SUCESS = (state, action) => {
    // console.log(state)
    let upList = action.payload.val() || {};
    upList = Object.keys(upList).map(function(k) {
      let item=upList[k];
      item.key=item.id;
      return item;
    }).reverse();
    // console.log(upList);
    return Object.assign({}, { upData: upList },state.upFetching:false);
  }
  //========================================================================
  //留言活动的reducer
  //========================================================================
const GETROOMS = 'GETROOMS',
  GETMESSAGES = 'GETMESSAGES',
  GETMOREMESSAGES = 'GETMOREMESSAGES',
  ADDROOM = 'ADDROOM',
  DELMESSAGES = 'DELMESSAGES',
  DELONEMESSAGE = 'DELONEMESSAGE',
  GETROOMSANDUP = 'GETROOMSANDUP',
  ADDMESSAGE = 'ADDMESSAGE',
  UPDATEMESSAGE = 'UPDATEMESSAGE';
export const getRooms = createAsyncAction(GETROOMS, () => {
  return roomMetaRef.orderByChild('createdAt').limitToLast(1000).once('value');
})
const GETROOMS_SUCESS = (state, action) => {
  // console.log(state)
  let roomList = action.payload.val() || {};
  roomList = Object.keys(roomList).map(function(k) {
    roomList[k].key = k;
    return roomList[k];
  }).reverse();
  // console.log(roomList);
  return Object.assign({}, state, { roomData: roomList , roomFetching:false});
}

export const addRoom = createAsyncAction(ADDROOM, (payload, dispatch) => {
  // console.log(payload);
  let newRoomRef = roomMetaRef.push();
  payload = Object.assign({}, payload, { createdAt: roomMetaRef.ServerValue.TIMESTAMP, id: newRoomRef.key() });
  console.log(payload, chatAppRef.ServerValue);
  return wilddog.sync().ref(`room-metadata/${newRoomRef.key()}`).set(payload).then(data => {
    dispatch(getRooms());
    return data;
  }).catch(err => console.log(err))
});



const ERROR = (state, action) => {
  console.log("请求失败了", action);
  return state
}


export const getMessages = createAsyncAction(GETMESSAGES, (roomId) => {
  // console.log(roomId)
  return roomMessageRef.ref(roomId).orderByChild('timestamp').limitToLast(2000).once('value');
})
const GETMESSAGES_SUCESS = (state, action) => {
  // console.log(state)
  let messageList = action.payload.val() || {};
  messageList = Object.keys(messageList).map(function(k) {
    messageList[k].id = k;
    return messageList[k];
  });
  // console.log(messageList.length);
  return Object.assign({}, state, { messageData: messageList.reverse(),messageFetching:false });
}
export const getMoreMessages = createAsyncAction(GETMOREMESSAGES, (payload) => {
  let {roomId,messageId}=payload;
  // console.log(roomId,messageId);
  return roomMessageRef.ref(roomId).orderByChild('timestamp').limitToFirst(2000).once('value');
})
const GETMOREMESSAGES_SUCESS = (state, action) => {
  let messageList = action.payload.val() || {};
  let orignMessage=state.messageData;
  let idArray=orignMessage.map(message=>message.id);
  messageList = Object.keys(messageList).map(function(k) {
    messageList[k].id = k;
    return messageList[k];
  });
  // console.log(messageList,orignMessage)
  messageList=messageList.filter(message=>{
    return !idArray.includes(message.id)
  }).reverse();
  // console.log(orignMessage.includes(messageList[100]),messageList[100]);
  let newMessageList=messageList?[...state.messageData,...messageList]:[...state.messageData]
  return Object.assign({}, state, { messageData:newMessageList,messageFetching:false });
}
export const delOneMessage = createAsyncAction(DELONEMESSAGE, (valueObj, dispatch) => {
  // console.log(valueObj)
  return wilddog.sync().ref(`room-messages/${valueObj.roomId}/${valueObj.id}`).set(null)
    .then(() => {
      return Promise.resolve(valueObj)
    })
    .catch((err) => {
      return Promise.reject(err)
    })
})
const DELONEMESSAGE_SUCESS = (state, action) => {

  return Object.assign({}, state, {
    messageData: state.messageData.filter((message) => {
      return message.id !== action.payload.id
    }),messageFetching:false
  });
}

export const delMessages=createAsyncAction(DELMESSAGES,(payload,dispatch)=>{
  let delQueue=[];
  let {messageInfo}=payload;
  messageInfo.map(id=>{delQueue.push(wilddog.sync().ref(`room-messages/${payload.roomId}/${id}`).set(null)); return id})
  // console.log(messageInfo);
  return Promise.all(delQueue).then(()=>Promise.resolve(messageInfo)).catch(err=>Promise.reject(err))
})
const DELMESSAGES_SUCESS = (state, action) => {
  // console.log(action)
  return Object.assign({}, state, {
    messageData: state.messageData.filter((message) => {
      return !action.payload.includes(message.id )
    }),messageFetching:false
  });
}
export const updateMessage = createAsyncAction(UPDATEMESSAGE, (valueObj, dispatch) => {
  // console.log(valueObj)
  return wilddog.sync().ref(`room-messages/${valueObj.roomId}/${valueObj.message.id}`).set(valueObj.message)
    .then(() =>  Promise.resolve(valueObj.message))
    .catch(err => Promise.reject(err));
})
const UPDATEMESSAGE_SUCESS = (state, action) => {
  return Object.assign({}, state, {
    messageData: state.messageData.map((message) => {
      if (message.id === action.payload.id) {
        return Object.assign({}, message, { checked: action.payload.checked })
      }
      return message;
    })
  ,messageFetching:false});
}
export const addMessage = createAsyncAction(ADDMESSAGE, (payload) => {
  let newRoomMessageRef = roomMessageRef.child(payload.roomId).push();
  let { roomId } = payload;
  payload = Object.assign({}, payload.messageInfo, { timestamp: roomMessageRef.ServerValue.TIMESTAMP, id: newRoomMessageRef.key() });
  // console.log(payload)
  return wilddog.sync().ref(`room-messages/${roomId}/${newRoomMessageRef.key()}`).set(payload).then(() =>
    Promise.resolve(payload)).catch(err=>Promise.reject(err));
})
const ADDMESSAGE_SUCESS = (state, action) => {
  // console.log(action)

  // console.log(messageList);
  return Object.assign({}, state, { messageData: [action.payload, ...state.messageData] ,messageFetching:false});
}





const GETPHOTOS = 'GETPHOTOS';

export const getPhotos = createAsyncAction(GETPHOTOS, () => {
  return wilddog.sync().ref("users").orderByKey().limitToLast(100).once("value")
})

const GETPHOTOS_SUCESS = (state, action) => {
  // console.log(action.payload.val());
  let userList = action.payload.val() || {};
  userList = Object.keys(userList).map(function(k) {
    return userList[k].photo;
  });
  return Object.assign({}, state, { photoData: userList });;
}

//========================================================================
//user相关的reducer
//========================================================================
const GETUSER = 'GETUSER';

export const getUser = createAsyncAction(GETUSER, (userId) => {
  return wilddog.sync().ref('users').child(userId).once('value')
    .then((data) => Promise.resolve(data.val())).catch((err) => Promise.reject(err))
})
const GETUSER_SUCESS = (state, action) => {

  let userInfo = action.payload || {};
  return Object.assign({}, state, {
    roomData: state.roomData.map(room => {
      if (room.createdByUserId === userInfo.id) {
        return Object.assign({}, room, { userInfo: userInfo })
      }
      return room
    })
  });
}
//========================================================================
//聊天室用户授权相关的reducer
//========================================================================
const AUTHORIZEUSER = 'AUTHORIZEUSER';

export const authorizeUser = createAsyncAction(AUTHORIZEUSER, (payload,dispatch) => {

  return wilddog.auth().signInWithPopup(provider).then(user=>{
    // console.log(user,payload);
    let userInfo={
      id:user.uid,
      photo:user.photoURL,
      name:user.displayName
    }
   return roomMetaRef.child(payload.id).child('authorizedUsers').child(user.uid).set(userInfo)
          .then(data=> Promise.resolve(user))
          .catch(err=>Promise.reject(err));
  }).catch(err=>Promise.reject(err));;
  // return  newRoomRef.set({...payload.userInfo,id:newRoomRef.key()}).then((data) => Promise.resolve(payload.userInfo)).catch((err) => Promise.reject(err))
    
})
const AUTHORIZEUSER_SUCESS = (state, action) => {

  let userInfo = action.payload || {};
  return Object.assign({}, state, {
    roomData: state.roomData.map(room => {
      if (room.createdByUserId === userInfo.id) {
        return Object.assign({}, room, { userInfo: userInfo })
      }
      return room
    })
  });
}

const upFetchingHandler=(state,action)=>{
  return Object.assign({},state,{upFetching:true})
}
const roomFetchingHandler=(state,action)=>{
  return Object.assign({},state,{roomFetching:true})
}
const meesageFetchingHandler=(state,action)=>{
  return Object.assign({},state,{messageFetching:true})
}
const wilddogReducer = createReducer()
  .when([ADDONEUP,DELETEONEUP,UPDATEUPCOUNT],upFetchingHandler)
  .when(GETUPLIST)
  .done(GETUPLIST_SUCESS)
  .when(GETROOMS,roomFetchingHandler)
  .done(GETROOMS_SUCESS)
  .when(GETMESSAGES,meesageFetchingHandler)
  .done(GETMESSAGES_SUCESS)
  .when(GETMOREMESSAGES,meesageFetchingHandler)
  .done(GETMOREMESSAGES_SUCESS)
  .when(DELONEMESSAGE,meesageFetchingHandler)
  .done(DELONEMESSAGE_SUCESS)
  .when(UPDATEMESSAGE,meesageFetchingHandler)
  .done(UPDATEMESSAGE_SUCESS)
  .when(ADDMESSAGE,meesageFetchingHandler)
  .done(ADDMESSAGE_SUCESS)
  .when(GETPHOTOS)
  .done(GETPHOTOS_SUCESS)
  .when(GETUSER)
  .done(GETUSER_SUCESS)
  .when(AUTHORIZEUSER)
  .done(AUTHORIZEUSER_SUCESS)
  .when(DELMESSAGES)
  .done(DELMESSAGES_SUCESS)
  .failed(ERROR)
  .build({ upData: [], messageData: [] ,upFetching:true,roomFetching:true,messageFetching:true});

export default wilddogReducer
